package com.sanq.product.mcgs.service.impl;

import com.google.common.base.Preconditions;
import com.sanq.product.config.utils.entity.Pager;
import com.sanq.product.config.utils.entity.Pagination;
import com.sanq.product.config.utils.string.StringUtil;
import com.sanq.product.config.utils.web.JsonUtil;
import com.sanq.product.mcgs.common.Redis;
import com.sanq.product.mcgs.entity.vo.PermissionVo;
import com.sanq.product.mcgs.mapper.PermissionMapper;
import com.sanq.product.mcgs.service.PermissionService;
import com.sanq.product.redis.service.JedisPoolService;
import com.sanq.product.security.enums.TokenTime;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;


@Service("permissionService")
public class PermissionServiceImpl implements PermissionService {

    @Resource
    private PermissionMapper permissionMapper;
    @Resource
    private JedisPoolService jedisPoolService;
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;

    private void deleteRedis(Integer memberId) {
        taskExecutor.execute(() -> {
            String key = Redis.ReplaceKey.getTreePermissionKey(memberId);
//            String buttonKey = Redis.ReplaceKey.getButtonPermissionKey(memberId);

            if (memberId == -1) {
                jedisPoolService.deletes(key);
//                jedisPoolService.deletes(buttonKey);
            } else {
                jedisPoolService.delete(key);
//                jedisPoolService.delete(buttonKey);
            }
        });
    }

    @Override
    public int save(PermissionVo permissionVo) {
        int save = permissionMapper.save(permissionVo);

        if (save != 0)
            deleteRedis(-1);

        return save;
    }

    @Override
    public int delete(PermissionVo permissionVo) {
        int delete = permissionMapper.delete(permissionVo);

        if (delete != 0)
            deleteRedis(-1);

        return delete;
    }

    @Override
    public int update(PermissionVo permissionVo, Integer id) {
        PermissionVo oldPermissionVo = findById(id);

        if (null != oldPermissionVo && null != permissionVo) {
            if (null != permissionVo.getId()) {
                oldPermissionVo.setId(permissionVo.getId());
            }
            if (null != permissionVo.getParentId()) {
                oldPermissionVo.setParentId(permissionVo.getParentId());
            }
            if (null != permissionVo.getPermissionType()) {
                oldPermissionVo.setPermissionType(permissionVo.getPermissionType());
            }
            if (null != permissionVo.getPermissionName()) {
                oldPermissionVo.setPermissionName(permissionVo.getPermissionName());
            }
            if (null != permissionVo.getPermissionUrl()) {
                oldPermissionVo.setPermissionUrl(permissionVo.getPermissionUrl());
            }
            if (null != permissionVo.getIsHome()) {
                oldPermissionVo.setIsHome(permissionVo.getIsHome());
            }
            if (null != permissionVo.getOrderNum()) {
                oldPermissionVo.setOrderNum(permissionVo.getOrderNum());
            }
            if (null != permissionVo.getCreateTime()) {
                oldPermissionVo.setCreateTime(permissionVo.getCreateTime());
            }
            if (null != permissionVo.getIcon()) {
                oldPermissionVo.setIcon(permissionVo.getIcon());
            }
            int update = permissionMapper.update(oldPermissionVo);

            if (update != 0)
                deleteRedis(-1);

            return update;
        }
        return 0;
    }

    @Override
    public PermissionVo findById(Integer id) {
        return permissionMapper.findById(id);
    }

    @Override
    public List<PermissionVo> findList(PermissionVo permissionVo, Integer type) {
        return permissionMapper.findList(permissionVo, type);
    }

    @Override
    public Pager<PermissionVo> findListByPage(PermissionVo permissionVo, Pagination pagination) {
        pagination.setTotalCount(findCount(permissionVo));

        List<PermissionVo> datas = permissionMapper.findListByPage(permissionVo, pagination.getStartPage(), pagination.getPageSize());

        return new Pager<PermissionVo>(pagination, datas);
    }

    @Override
    public int findCount(PermissionVo permissionVo) {
        return permissionMapper.findCount(permissionVo);
    }

    @Override
    public void saveByList(List<PermissionVo> permissionVos) {
        permissionMapper.saveByList(permissionVos);
    }

    @Override
    public List<PermissionVo> getPermissionByParentList(Integer parentId) {
        return permissionMapper.getPermissionByParentList(parentId);
    }

    @Override
    public List<PermissionVo> findPermissionByMemberId(Integer parentId, Integer memberId) {
        String key = Redis.ReplaceKey.getTreePermissionKey(memberId);

        String json = jedisPoolService.get(key);

        List<PermissionVo> resultList;
        if (StringUtil.isEmpty(json)) {
            List<PermissionVo> voList = permissionMapper.findPermissionByMemberId(parentId, memberId);
            resultList = findChildList(voList, memberId);

            Preconditions.checkNotNull(resultList);

            jedisPoolService.set(key, JsonUtil.obj2Json(resultList), TokenTime.TOKEN_TIME.getTime());
        } else resultList = JsonUtil.json2ObjList(json, PermissionVo.class);

        return resultList;
    }

    private final List<PermissionVo> findChildList(List<PermissionVo> list, Integer memberId) {
        if (list == null || list.isEmpty())
            return list;

        for (PermissionVo permissionVo : list) {
            permissionVo.setChilds(findChildList(permissionMapper.findPermissionByMemberId(permissionVo.getId(), memberId), memberId));
        }

        return list;
    }

    @Override
    public void findPermissionUrlByMemberId(Integer id) {
        String key = Redis.ReplaceKey.getButtonPermissionKey(id);

        List<String> permissionUrlList = permissionMapper.findPermissionUrlByMemberId(id);

        Preconditions.checkNotNull(permissionUrlList);

        jedisPoolService.set(key, JsonUtil.obj2Json(permissionUrlList), TokenTime.TOKEN_TIME.getTime());
    }
}